/**
 * Copyright (c) 2016-2100 yunclouds
 */
package com.yunqian.redot.service;

import com.alibaba.fastjson.JSON;
import com.yunqian.exception.ServiceException;
import com.yunqian.redot.constant.RefundStatus;
import com.yunqian.redot.domain.Ticket;
import com.yunqian.redot.domain.TicketOrder;
import com.yunqian.redot.repository.TicketOrderRepository;
import com.yunqian.service.BaseService;
import com.yunqian.util.RandomUtil;
import com.yunqian.util.ZPTUtil;
import com.yunqian.util.swiftpass.SwiftpassUtil;
import com.yunqian.util.validate.Validator;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 客户门票订单记录
 *
 * @author zsy
 * 2018-09-29 15:55:07
 */
@Service
@Log4j2
public class TicketOrderService extends BaseService<TicketOrder, Long> {

    @Autowired
    private TicketOrderRepository ticketOrderRepository;
    @Autowired
    private TicketService ticketService;
    @Autowired
    private SwiftpassPayService swiftpassPayService;

    public void updateOrderStatus() {
        // 增加库存
        ticketService.addStock();
        // 更新订单状态
        ticketOrderRepository.updateOrderStatus();
    }

    public TicketOrder findByOrderNo(String orderNo) {
        return ticketOrderRepository.findByOrderNo(orderNo);
    }

    public Map<String, String> saveOrder(TicketOrder ticketOrder, String openId, String ip) {
        // 检票
        checkTicket(ticketOrder);
        // 校验库存
        checkStock(ticketOrder);
        // 保存订单
        String orderNo = "NO" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + RandomUtil.fourDigit();
        ticketOrder.setOrderNo(orderNo);
        TicketOrder order = super.save(ticketOrder);
        // 订单支付 -预下单
        Map<String, String> params = SwiftpassUtil.prepayment(order.getOrderNo(), "门票订单", openId, "ticket_order", String.valueOf(order.getPrice().multiply(new BigDecimal(order.getQuantity()))), ip);
        params.put("orderId", order.getId().toString());
        // 下单成功减除库存 套票不减
        if(Validator.isNotNull(order.getTicketId())){
            boolean exist = ticketService.existsByTypeAndStatusAndId(order.getTicketId());
            if(exist){
                ticketService.subtractStock(order.getTicketId(), order.getQuantity());
            }
        }
        // 保存预支付信息
        swiftpassPayService.save(order.getOrderNo(), params);
        return params;
    }

    public void refund(TicketOrder order) {
        // 如果已退款成功则什么都不做
        if(Validator.equals(order.getRefundStatus(),RefundStatus.SUCCESS.getCode())){
            return;
        }
        Map<String, String> resultMap = SwiftpassUtil.refund(order.getOrderNo(), order.getOrderNo(), order.getTotalPrice().toString(), order.getTotalPrice().toString());
        log.warn("退款中,订单号:" + order.getOrderNo() + "退款结果: " + JSON.toJSONString(resultMap));
        if ("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))) {
            // 退款成功
            log.warn("订单号：" + order.getOrderNo() + "退款成功!");
            order.setRefundStatus(RefundStatus.SUCCESS.getCode());
            // zpt取消订单
            Integer state = ZPTUtil.cancelOrder(order.getOrderNo(), order.getOrderNo(),order.getQuantity().toString(), order.getOrderNo());
            order.setState(state);
        } else {
            // 退款失败
            log.warn("订单号：" + order.getOrderNo() + "退款失败!");
            order.setRefundStatus(RefundStatus.FAIL.getCode());
        }
        order.setRefundResult(JSON.toJSONString(resultMap));
        super.update(order);
    }

    /**
     * 将字符串转为List
     *
     * @param str
     * @return
     */
    private List<Long> strToLongList(String str) {
        String[] strArr = str.substring(1, str.length() - 1).split(",");
        List<Long> list = new ArrayList<>();
        for (int i = 0; i < strArr.length; i++) {
            list.add(Long.valueOf(strArr[i]));
        }
        return list;
    }

    /**
     * 检票
     *
     * @param ticketOrder
     */
    private void checkTicket(TicketOrder ticketOrder) {

        String ticketStr = ticketOrder.getRelateTicketArr();
        // 所有门票
        List<Ticket> ticketList = ticketService.findAll();
        // 是否匹配上基本票或者套票标识
        boolean flag = true;
        // 单人票价
        BigDecimal price = new BigDecimal(0);
        //总价 票价*人数
        BigDecimal totalPrice = new BigDecimal(0);
        for (Ticket ticket : ticketList) {
            if (ticket.getRelateTicketArr().equals(ticketStr)) {
                flag = false;
                price = ticket.getPrice();
                totalPrice = ticket.getPrice().multiply(new BigDecimal(ticketOrder.getQuantity()));
                // 关联门票Id
                ticketOrder.setTicketId(ticket.getId());
                break;
            }
        }
        // 没匹配上，按基本票的价格相加
        if (flag) {
            throw new ServiceException("下单失败，没有匹配上该票种，请联系管理人员！");
        }
        // 校验价格
        DecimalFormat df = new DecimalFormat("#0.00");
        if (price.compareTo(new BigDecimal(df.format(ticketOrder.getPrice()))) != 0) {
            throw new ServiceException("票价错误");
        }
        if (totalPrice.compareTo(new BigDecimal(df.format(ticketOrder.getTotalPrice()))) != 0) {
            throw new ServiceException("总票价错误");
        }
    }

    public void checkStock(TicketOrder order){
        List<Ticket> ticketList = ticketService.findAllByType();
        ticketList.forEach(item -> {
            if(item.getId().equals(order.getTicketId())){
                Integer newStock = item.getStock() - order.getQuantity();
                if(newStock < 0){
                    throw new ServiceException("库存不足");
                }
            }
        });

    }
}
